package cn.vire.electric.simulation.common.dto;

import cn.vire.electric.simulation.common.exception.BusinessException;
import cn.vire.electric.simulation.config.filter.CommonFilter;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.slf4j.MDC;
import org.springframework.http.HttpStatus;

import java.io.Serializable;
import java.util.Date;

@Data
@ToString
@NoArgsConstructor
@ApiModel("接口通用数据结构")
public class Result<T> implements Serializable {

    @ApiModelProperty("是否成功[true,false]")
    private boolean success = true;
    @ApiModelProperty("状态码")
    private int code;
    @ApiModelProperty("返回消息")
    private String msg;
    @ApiModelProperty("数据")
    private T data;
    @ApiModelProperty("当前请求链路ID,用于后台日志定位")
    private String requestId = MDC.get(CommonFilter.REQUESTID);//日志格式添加请求链
    @ApiModelProperty("响应时间戳")
    private Date time = new Date();

    public Result(boolean success, int code, String msg, T data) {
        this.success = success;
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public Result(Throwable cause) {
        this.success = false;
        this.code = 500;
        this.msg = cause.getMessage();
    }


    public static Result ok() {
        return new Result<>(true, HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), null);
    }

    public static <T> Result<T> ok(T data) {
        return new Result<>(true, HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), data);
    }

    public static <T> Result<T> ok(int code, String msg, T data) {
        return new Result<>(true, code, msg, data);
    }

    public static <T> Result<T> fail(int code, String msg) {
        return new Result<>(false, code, msg, null);
    }

    public static <T> Result<T> fail(int code, String msg, T data) {
        return new Result<>(false, code, msg, data);
    }

    public static <T> Result<T> fail(HttpStatus result) {
        return new Result<>(false, result.value(), result.getReasonPhrase(), null);
    }

    public static <T> Result<T> fail(HttpStatus result, String msg) {
        return new Result<>(false, result.value(), msg, null);
    }

    public static <T> Result<T> fail(String msg) {
        return new Result<>(false, HttpStatus.BAD_REQUEST.value(), msg, null);
    }

    public static Result fail(Throwable e) {
        int code = 500;
        if (e instanceof BusinessException) {
            code = ((BusinessException) e).getCode();
        }
        return new Result(false, code, e.getMessage(), null);
    }


}
